﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using Moq;
using NUnit.Framework;
using Secure.Client;
using VitaminK.Extensions;

namespace Secure.Tests.Client
{
    [TestFixture]
    public class GatewayClientFixture
    {
        [Test]
        public void gateway_client_should_use_identity_provider_to_resolve_user_names()
        {
            var identityProvider = new Mock<IIdentityProvider>();
            identityProvider.SetupGet(x => x.CurrentUserIsIdentified).Returns(true);
            identityProvider.SetupGet(x => x.CurrentUserId).Returns("MyDomain\\SomeUser");

            var gatewayService = new Mock<IGatewayService>();
            gatewayService.Setup(service => service.GetSecurityToken("MyApplication", "MySecretKey")).Returns("MyToken");

            string[] expectedAdditionalParameters = new[] {"653271"};
            gatewayService.Setup(
                service =>
                service.IsAllowedAccess(out expectedAdditionalParameters, "MyToken", "MyDomain\\SomeUser", "application/MyApplication/GetAccount")).Returns(true);

            ISecureClient client = new SecureClient("MyApplication", "MySecretKey", identityProvider.Object, gatewayService.Object);

            string[] additionalParameters;
            bool isAuthorised = client.IsUserInRole(null, "GetAccount", out additionalParameters);

            Assert.IsTrue(isAuthorised);

            identityProvider.VerifyGet(x => x.CurrentUserIsIdentified);
            identityProvider.VerifyGet(x => x.CurrentUserId);
        }

        [Test]
        public void should_retrieve_only_one_token_from_the_gateway_service()
        {
            var identityProvider = new Mock<IIdentityProvider>();
            identityProvider.SetupGet(x => x.CurrentUserIsIdentified).Returns(true);
            identityProvider.SetupGet(x => x.CurrentUserId).Returns("MyDomain\\SomeUser");

            var gatewayService = new Mock<IGatewayService>();
            gatewayService.Setup(service => service.GetSecurityToken("MyApplication", "MySecretKey")).Returns("MyToken").AtMostOnce();

            string[] expectedAdditionalParameters = new[] {"653271"};
            gatewayService.Setup(
                service =>
                service.IsAllowedAccess(out expectedAdditionalParameters, "MyToken", "MyDomain\\SomeUser", "application/MyApplication/GetAccount"))
                .Returns(true);

            ISecureClient client = new SecureClient("MyApplication", "MySecretKey", identityProvider.Object, gatewayService.Object);

            string[] additionalParameters;
            bool isAuthorised = client.IsUserInRole(null, "GetAccount", out additionalParameters);

            Assert.IsTrue(isAuthorised);
            Assert.AreEqual(new [] {"653271"}, additionalParameters);

            isAuthorised = client.IsUserInRole(null, "GetAccount", out additionalParameters);

            Assert.IsTrue(isAuthorised); // second method call to ensure the client only requests one token
        }
    }
}
